#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
班次标识符映射工具

用于处理班次标识符的转换，支持以下映射：
1. 数字标识符("1", "2", "3") <-> 新内部标识符("one_shift", "two_shift", "three_shift")
2. 新内部标识符("one_shift", "two_shift", "three_shift") <-> 旧内部标识符("morning_shift", "afternoon_shift", "night_shift")

作者: AI助手
日期: 2023-05-21
"""

import logging

logger = logging.getLogger(__name__)

class ShiftIdMapper:
    """班次标识符映射器"""

    # 数字到新内部标识符的映射
    NUMERIC_TO_INTERNAL = {
        "1": "one_shift",
        "2": "two_shift",
        "3": "three_shift",
        1: "one_shift",
        2: "two_shift",
        3: "three_shift"
    }

    # 新内部标识符到数字的映射
    INTERNAL_TO_NUMERIC = {
        "one_shift": "1",
        "two_shift": "2",
        "three_shift": "3"
    }

    # 新内部标识符到旧内部标识符的映射
    INTERNAL_TO_LEGACY = {
        "one_shift": "morning_shift",
        "two_shift": "afternoon_shift",
        "three_shift": "night_shift"
    }

    # 旧内部标识符到新内部标识符的映射
    LEGACY_TO_INTERNAL = {
        "morning_shift": "one_shift",
        "afternoon_shift": "two_shift",
        "night_shift": "three_shift"
    }

    # 数字到旧内部标识符的直接映射（用于兼容）
    NUMERIC_TO_LEGACY = {
        "1": "one_shift",
        "2": "two_shift",
        "3": "three_shift",
        1: "one_shift",
        2: "two_shift",
        3: "three_shift"
    }

    # 旧内部标识符到数字的直接映射（用于兼容）
    LEGACY_TO_NUMERIC = {
        "morning_shift": "1",
        "afternoon_shift": "2",
        "night_shift": "3",
        "one_shift": "1",
        "two_shift": "2",
        "three_shift": "3"
    }

    @classmethod
    def to_internal_id(cls, shift_id):
        """将任意标识符转换为内部标识符

        Args:
            shift_id: 可以是数字(1,2,3)、字符串数字("1","2","3")或旧内部标识符("morning_shift"等)

        Returns:
            str: 内部标识符("one_shift"等)
        """
        # 如果是数字或字符串数字
        if shift_id in cls.NUMERIC_TO_INTERNAL:
            return cls.NUMERIC_TO_INTERNAL[shift_id]

        # 如果是旧内部标识符
        if shift_id in cls.LEGACY_TO_INTERNAL:
            return cls.LEGACY_TO_INTERNAL[shift_id]

        # 如果已经是内部标识符
        if shift_id in cls.INTERNAL_TO_NUMERIC:
            return shift_id

        # 无法识别的标识符
        logger.warning(f"无法识别的班次标识符: {shift_id}，返回原值")
        return shift_id

    @classmethod
    def to_numeric_id(cls, shift_id):
        """将任意标识符转换为数字标识符

        Args:
            shift_id: 可以是内部标识符("one_shift"等)或旧内部标识符("morning_shift"等)

        Returns:
            str: 数字标识符("1","2","3")
        """
        # 如果是内部标识符
        if shift_id in cls.INTERNAL_TO_NUMERIC:
            return cls.INTERNAL_TO_NUMERIC[shift_id]

        # 如果是旧内部标识符
        if shift_id in cls.LEGACY_TO_NUMERIC:
            return cls.LEGACY_TO_NUMERIC[shift_id]

        # 如果已经是数字标识符
        if str(shift_id) in ["1", "2", "3"]:
            return str(shift_id)

        # 无法识别的标识符
        logger.warning(f"无法识别的班次标识符: {shift_id}，返回原值")
        return shift_id

    @classmethod
    def to_legacy_id(cls, shift_id):
        """将任意标识符转换为新的内部标识符（用于兼容）

        Args:
            shift_id: 可以是数字(1,2,3)、字符串数字("1","2","3")或内部标识符("one_shift"等)

        Returns:
            str: 新的内部标识符("one_shift"等)
        """
        # 如果是数字或字符串数字
        if shift_id in cls.NUMERIC_TO_LEGACY:
            return cls.NUMERIC_TO_LEGACY[shift_id]

        # 如果是旧内部标识符，转换为新的内部标识符
        if shift_id in cls.LEGACY_TO_INTERNAL:
            return cls.LEGACY_TO_INTERNAL[shift_id]

        # 如果已经是新的内部标识符
        if shift_id in ["one_shift", "two_shift", "three_shift"]:
            return shift_id

        # 无法识别的标识符
        logger.warning(f"无法识别的班次标识符: {shift_id}，返回原值")
        return shift_id

    @classmethod
    def convert_shift_list(cls, shift_list, target_format="internal"):
        """转换班次列表的标识符格式

        Args:
            shift_list: 班次标识符列表
            target_format: 目标格式，可选值：
                - "internal": 转换为内部标识符("one_shift"等)
                - "numeric": 转换为数字标识符("1","2","3")
                - "legacy": 转换为旧内部标识符("morning_shift"等)

        Returns:
            list: 转换后的班次列表
        """
        if not shift_list:
            return []

        converted_list = []
        for shift_id in shift_list:
            if target_format == "internal":
                converted_list.append(cls.to_internal_id(shift_id))
            elif target_format == "numeric":
                converted_list.append(cls.to_numeric_id(shift_id))
            elif target_format == "legacy":
                converted_list.append(cls.to_legacy_id(shift_id))
            else:
                logger.warning(f"未知的目标格式: {target_format}，返回原值")
                converted_list.append(shift_id)

        return converted_list

    @classmethod
    def get_shift_name(cls, shift_id, language="zh"):
        """获取班次的显示名称

        Args:
            shift_id: 任意格式的班次标识符
            language: 语言，可选值："zh"(中文)、"en"(英文)

        Returns:
            str: 班次显示名称
        """
        # 转换为内部标识符
        internal_id = cls.to_internal_id(shift_id)

        # 中文名称映射
        zh_names = {
            "one_shift": "班次1",
            "two_shift": "班次2",
            "three_shift": "班次3"
        }

        # 英文名称映射
        en_names = {
            "one_shift": "Shift 1",
            "two_shift": "Shift 2",
            "three_shift": "Shift 3"
        }

        # 根据语言返回名称
        if language == "zh":
            return zh_names.get(internal_id, f"未知班次({internal_id})")
        elif language == "en":
            return en_names.get(internal_id, f"Unknown Shift({internal_id})")
        else:
            logger.warning(f"未知的语言: {language}，使用中文")
            return zh_names.get(internal_id, f"未知班次({internal_id})")


# 单元测试
if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    )

    # 测试数字到内部标识符的转换
    assert ShiftIdMapper.to_internal_id("1") == "one_shift"
    assert ShiftIdMapper.to_internal_id(2) == "two_shift"
    assert ShiftIdMapper.to_internal_id("3") == "three_shift"

    # 测试旧内部标识符到内部标识符的转换
    assert ShiftIdMapper.to_internal_id("morning_shift") == "one_shift"
    assert ShiftIdMapper.to_internal_id("afternoon_shift") == "two_shift"
    assert ShiftIdMapper.to_internal_id("night_shift") == "three_shift"

    # 测试内部标识符到数字的转换
    assert ShiftIdMapper.to_numeric_id("one_shift") == "1"
    assert ShiftIdMapper.to_numeric_id("two_shift") == "2"
    assert ShiftIdMapper.to_numeric_id("three_shift") == "3"

    # 测试旧内部标识符到数字的转换
    assert ShiftIdMapper.to_numeric_id("morning_shift") == "1"
    assert ShiftIdMapper.to_numeric_id("afternoon_shift") == "2"
    assert ShiftIdMapper.to_numeric_id("night_shift") == "3"

    # 测试数字到新内部标识符的转换
    assert ShiftIdMapper.to_legacy_id("1") == "one_shift"
    assert ShiftIdMapper.to_legacy_id(2) == "two_shift"
    assert ShiftIdMapper.to_legacy_id("3") == "three_shift"

    # 测试旧内部标识符到新内部标识符的转换
    assert ShiftIdMapper.to_legacy_id("morning_shift") == "one_shift"
    assert ShiftIdMapper.to_legacy_id("afternoon_shift") == "two_shift"
    assert ShiftIdMapper.to_legacy_id("night_shift") == "three_shift"

    # 测试班次列表转换
    assert ShiftIdMapper.convert_shift_list(["1", "2", "3"], "internal") == ["one_shift", "two_shift", "three_shift"]
    assert ShiftIdMapper.convert_shift_list(["morning_shift", "afternoon_shift"], "numeric") == ["1", "2"]
    assert ShiftIdMapper.convert_shift_list(["one_shift", "two_shift"], "legacy") == ["one_shift", "two_shift"]
    assert ShiftIdMapper.convert_shift_list(["morning_shift", "afternoon_shift"], "legacy") == ["one_shift", "two_shift"]

    # 测试获取班次名称
    assert ShiftIdMapper.get_shift_name("1", "zh") == "班次1"
    assert ShiftIdMapper.get_shift_name("two_shift", "en") == "Shift 2"
    assert ShiftIdMapper.get_shift_name("night_shift", "zh") == "班次3"

    print("所有测试通过！")
